#ifndef _EVENTLOOP_H
#define _EVENTLOOP_H

#include "Channel.h"
#include "CurrentThread.h"
#include "Epoll.h"
#include "Logging.h"
#include "mutex.h"
#include "thread.h"
#include "utils.h"

#include <functional>
#include <iostream>
#include <memory.h>
#include <memory>
#include <mutex>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <sys/socket.h>
#include <vector>
using namespace monsoon;
namespace droneswarm
{
    class EventLoop
    {
    public:
        typedef std::function< void() > Functor;
        EventLoop();
        ~EventLoop();

        void loop();                       //开启事件循环
        void quit();                       //退出事件循环
        void runInLoop( Functor &&cb );    //在当前IO线程执行cb
        void queueInLoop( Functor &&cb );  //将cb放入队列中，唤醒IO线程执行cb

        //这两个函数是用于判断当前代码是否在事件循环线程中执行的。
        bool isInLoopThread() const { return threadId_ == tid(); }
        void assertInLoopThread() { CondPanic( isInLoopThread(), "assertInLoopThread is failed!" ); }

        void shutdown( std::shared_ptr< Channel > channel ) { shutDownWR( channel->get_fd() ); }
        //从epoll实例中删除传递过来的channel
        void removeFromPoller( std::shared_ptr< Channel > channel )
        {
            // std::cout << "4:removeFromPoller" << std::endl;
            poller_->epoll_del( channel );
        }
        //从epoll实例中更新传递过来的channel
        void updatePoller( std::shared_ptr< Channel > channel, int timeout = 0 ) { poller_->epoll_mod( channel, timeout ); }
        //从epoll实例中添加递过来的channel
        void addToPoller( std::shared_ptr< Channel > channel, int timeout = 0 ) { poller_->epoll_add( channel, timeout ); }
        void doPendingFunctors();

    private:
        bool looping_;                            //是否在事件循环
        std::shared_ptr< Epoll > poller_;         //指向epoll实例的指针
        int wakeupFd_;                            //用于唤醒IO线程的文件描述符
        bool quit_;                               //是否退出事件循环
        bool eventHandling_;                      //是否在处理事件
        mutable std::mutex mutex_;                //互斥锁
        std::vector< Functor > pendingFunctors_;  //存放需要执行的回调函数
        bool callingPendingFunctors_;             //是否正在执行回调函数
        const pid_t threadId_;                    // 事件循环线程的id
        std::shared_ptr< Channel >
            pwakeupChannel_;  //这个Channel用来异步唤醒subLoopd的epoll_wait(向event_fd_写入数据，唤醒epoll_wait)

        void wakeup();              //唤醒IO线程
        void handleRead();          //处理读事件
                                    //执行回调函数
        void handleupdateWakeup();  //处理唤醒事件处理完毕后，更新pwakeupChannel_的事件类型
    };
}  // namespace droneswarm
#endif